package com.tian.config;

import com.tian.mqtt.callbeck.MqttCallback;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttClientPersistence;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author tianwc  公众号：java后端技术全栈、面试专栏
 * @version 1.0.0
 * 2023年11月05日 22:41
 * 在线刷题 1200+题和1000+篇干货文章：<a href="https://woaijava.cc/">博客地址</a>
 * <p>
 * https://blog.csdn.net/qq_47910339/article/details/131276965
 * <p>
 * D:\tool\other\mqtt
 * 设备上下线
 * https://blog.csdn.net/qq_34565436/article/details/123686387
 * https://blog.csdn.net/weixin_38405253/article/details/119723051
 */
@Slf4j
@Configuration
public class MqttClientConfig {

    @Value("${server.mqtt.uri}")
    private String serverMqttUri;

    @Value("${client.mqtt.gun}")
    private String clientMqttGun;

    @Value("${client.mqtt.server}")
    private String clientMqttGunServer;

    @Bean
    public MqttClient client4Publish() {
        return getMqttClient(serverMqttUri, clientMqttGun);
    }

    @Bean
    public MqttClient client4Subscribe() {
        MqttClient client = getMqttClient(serverMqttUri, clientMqttGunServer);
        client.setCallback(new MqttCallback());
        return client;
    }

    private MqttClient getMqttClient(String serverUri, String clientId) {
        MqttClientPersistence persistence = new MemoryPersistence();
        MqttClient client;
        try {
            client = new MqttClient(serverUri, clientId, persistence);
        } catch (MqttException e) {
            log.error("create mqtt client failed:", e);
            throw new RuntimeException(e);
        }
        //连接选项中定义用户名密码和其它配置
        MqttConnectOptions options = new MqttConnectOptions();
        //参数为true表示清除缓存，也就是非持久化订阅者，这个时候只要参数设为true，一定是非持久化订阅者。而参数设为false时，表示服务器保留客户端的连接记录
        options.setCleanSession(true);
        //是否自动重连
        options.setAutomaticReconnect(true);
        //连接超时时间  秒
        options.setConnectionTimeout(30);
        //连接保持检查周期  秒
        options.setKeepAliveInterval(10);
        //版本
        options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
        //连接
        try {
            client.connect(options);
        } catch (MqttException e) {
            log.error("connect mqtt failed:", e);
            throw new RuntimeException(e);
        }
        return client;
    }
}
